home *** CD-ROM | disk | FTP | other *** search
- This is some TASM code for detecting the IRQ and interupt of a Sound Blaster
- card. Use it well!
-
- The Bunny Hunter
-
- --------------------------------- Cut Here -------------------------------
-
- WAIT_TIME EQU 000FFh
- DSP_INTRQ_CMD EQU 000F2h
-
- DATA SEGMENT WORD PUBLIC
-
- EXTRN SBInt : WORD;
- EXTRN SBIrq : WORD;
-
- ORG_INT2_ADDX DD 0;
- ORG_INT3_ADDX DD 0;
- ORG_INT5_ADDX DD 0;
- ORG_INT7_ADDX DD 0;
-
- DATA ENDS
-
- CODE SEGMENT WORD PUBLIC
- ASSUME CS:CODE,DS:DATA
-
- ;════════════════════════════════════════════════════════
- ;
- ; ResetDSP - reset the DSP
- ;
- ;════════════════════════════════════════════════════════
-
- ResetDSP PROC
-
- MOV DX,SBInt
- ADD DL,6 ; DX = DSP reset port 2x6h
- MOV AL,1
- OUT DX,AL ; write 1, then wait 3 micro-seconds
-
- IN AL,DX ; read value from DSP
- RDSP05:
- INC AL
- JNZ RDSP05 ; wait until AL = 0
-
- OUT DX,AL ; write 0
-
- MOV CL,20H ; set reset timeout value
-
- RDSP10:
- CALL ReadDSPTime ; read from DSP
- CMP AL,0AAH ; if byte is 0AAh then
- JE RDSP20 ; DSP is reset, exit
-
- LOOP RDSP10 ; not reset, try again
-
- MOV AX,2 ; set I/O failure error
- JMP SHORT RDSP90 ; exit;
-
- RDSP20:
- XOR AX,AX ; clear AX, no error
-
- RDSP90:
- OR AX,AX ; set flags for return
-
- RET
-
- ResetDSP ENDP
-
- ;════════════════════════════════════════════════════════
- ;
- ; ReadDSPTime - read from DSP with timeout
- ;
- ;════════════════════════════════════════════════════════
-
- ReadDSPTime PROC
-
- PUSH CX
- PUSH DX
-
- MOV DX,SBInt
- ADD DL,0EH ; DX = DSP data available port 2xEh
-
- MOV CX,WAIT_TIME ; load timeout value into CX
-
- RDT10:
- IN AL,DX ; check to see if DSP is ready
- OR AL,AL
- JS RDT20 ; if sign set, then DSP read ready
-
- LOOP RDT10 ; not ready, keep waiting
-
- STC ; set error, DSP read timeout
- JMP SHORT RDT90 ; exit
-
- RDT20:
- SUB DL,4 ; DX = DSP read data port 2xAh
- IN AL,DX ; read byte from DSP
- CLC ; clear error
-
- RDT90:
- POP DX
- POP CX
-
- RET
-
- ReadDSPTime ENDP
-
- ;════════════════════════════════════════════════════════
- ;
- ; CheckSBInt - detect DMA interrupt
- ;
- ;════════════════════════════════════════════════════════
-
- PUBLIC CheckSBInt
-
- CheckSBInt PROC FAR
-
- push bp
- mov bp,sp
-
- MOV AL,2 ; setup end of DMA
- MOV DX,OFFSET DUMMY_DMA_INT2 ; interrupts for all
- MOV BX,OFFSET DATA:ORG_INT2_ADDX ; possible IRQs
- CALL SetupInterrupt ; (2, 3, 5, and 7)
-
- MOV AL,3
- MOV DX,OFFSET DUMMY_DMA_INT3
- MOV BX,OFFSET DATA:ORG_INT3_ADDX
- CALL SetupInterrupt
-
- MOV AL,5
- MOV DX,OFFSET DUMMY_DMA_INT5
- MOV BX,OFFSET DATA:ORG_INT5_ADDX
- CALL SetupInterrupt
-
- MOV AL,7
- MOV DX,OFFSET DUMMY_DMA_INT7
- MOV BX,OFFSET DATA:ORG_INT7_ADDX
- CALL SetupInterrupt
-
- MOV SBIrq,0 ; reset current IRQ
-
- MOV DX,SBInt
- ADD DX,0CH ; DX = DSP write port 2xCh
- MOV AL,DSP_INTRQ_CMD ; AL = interrupt request command
- CALL WriteDSP ; write command to DSP
-
- XOR AX,AX ; assume success
- MOV CX,WAIT_TIME ; load timeout value into CX
- CLD
-
- VI10:
- CMP SBIrq,0 ; see if interrupt has been changed
- JNE VI90 ; if so, continue
-
- LOOP VI10 ; if not, keep waiting
-
- MOV AX,0FFh ; set DMA failure error
-
- VI90:
- PUSH AX ; save result variable
-
- MOV AL,2 ; restore end of DMA
- MOV BX,OFFSET DATA:ORG_INT2_ADDX ; interrupts
- CALL RestoreInterrupt
-
- MOV AL,3
- MOV BX,OFFSET DATA:ORG_INT3_ADDX
- CALL RestoreInterrupt
-
- MOV AL,5
- MOV BX,OFFSET DATA:ORG_INT5_ADDX
- CALL RestoreInterrupt
-
- MOV AL,7
- MOV BX,OFFSET DATA:ORG_INT7_ADDX
- CALL RestoreInterrupt
-
- POP AX ; restore result
-
- OR AX,AX
-
- mov sp,bp
- pop bp
-
- RET
-
- CheckSBInt ENDP
-
- ;════════════════════════════════════════════════════════
- ;
- ; WriteDSP
- ;
- ;════════════════════════════════════════════════════════
-
- WriteDSP PROC
-
- PUSH CX
-
- MOV AH,AL ; save value in AL for later
-
- MOV CX,WAIT_TIME
-
- WD10:
- IN AL,DX ; check to see if DSP is ready
- OR AL,AL
- JNS WD20 ; if sign set, DSP not write ready
- LOOP WD10
-
- WD20:
- MOV AL,AH ; restore AL
- OUT DX,AL ; send byte to DSP
-
- POP CX
-
- RET
-
- WriteDSP ENDP
-
- ;════════════════════════════════════════════════════════
- ;
- ; SetupInterrupt
- ;
- ;════════════════════════════════════════════════════════
-
- SetupInterrupt PROC
-
- PUSH BX
- PUSH CX
- PUSH DX
-
- CLI
-
- MOV CL,AL ; preserve interrupt number for use
-
- ADD AL,8 ; calculate interrupt vector addx
- CBW
- SHL AL,1
- SHL AL,1
- MOV DI,AX
-
- PUSH ES ; setup and preserve interrupt
- XOR AX,AX
- MOV ES,AX
- MOV AX,ES:[DI]
- MOV [BX],AX
- MOV ES:[DI],DX
-
- MOV AX,ES:[DI+2]
- MOV [BX+2],AX
- MOV ES:[DI+2],CS
-
- POP ES
-
- MOV AH,1 ; enable interrupt control mask-bit
- SHL AH,CL
- NOT AH
-
- IN AL,21H
- AND AL,AH
- OUT 21H,AL
-
- STI
-
- POP DX
- POP CX
- POP BX
-
- RET
-
- SetupInterrupt ENDP
-
-
- ;════════════════════════════════════════════════════════
- ;
- ; RestoreInterrupt
- ;
- ; ENTRY: AL = INTERRUPT NUM
- ; BX = offset to stored addx
- ;
- ;════════════════════════════════════════════════════════
-
- RestoreInterrupt PROC
-
- CLI
-
- MOV CL,AL
-
- ADD AL,8 ; calculate interrupt vector addx
- CBW
- SHL AL,1
- SHL AL,1
- MOV DI,AX
-
- PUSH ES ; restore interrupt vector
- XOR AX,AX
- MOV ES,AX
- MOV AX,[BX]
- MOV ES:[DI],AX
-
- MOV AX,[BX+2]
- MOV ES:[DI+2],AX
-
- POP ES
-
- MOV AH,1
- SHL AH,CL
-
- IN AL,21H
- OR AL,AH
- OUT 21H,AL
-
- STI
-
- RET
-
- RestoreInterrupt ENDP
-
- ;════════════════════════════════════════════════════════
- ;
- ; DUMMY INTERRUPTS - used for interrupt detection
- ;
- ;════════════════════════════════════════════════════════
-
- DUMMY_DMA_INT2 PROC FAR
-
- PUSH DX
- MOV DX,2
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT2 ENDP
-
-
- DUMMY_DMA_INT3 PROC FAR
-
- PUSH DX
- MOV DX,3
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT3 ENDP
-
-
- DUMMY_DMA_INT5 PROC FAR
-
- PUSH DX
- MOV DX,5
- JMP SHORT DUMMY_DMA_ISR
-
- DUMMY_DMA_INT5 ENDP
-
-
- DUMMY_DMA_INT7 PROC FAR
-
- PUSH DX
- MOV DX,7
-
- DUMMY_DMA_ISR:
- PUSH AX
- PUSH DS
-
- MOV AX,DATA
- MOV DS,AX
-
- MOV SBIrq,DX ; update interrupt variable with
- ; number of interrupt called
- MOV DX,SBInt
- ADD DX,0EH ; DX = DSP data available port 2xEh
- IN AL,DX ; acknowledge DSP interrupt
-
- MOV AL,20H ; send EOI (end of interrupt) to
- OUT 20H,AL ; interrupt controller port 20h
-
- POP DS
- POP AX
- POP DX
- IRET ; interrupt return
-
- DUMMY_DMA_INT7 ENDP
-
- CODE ENDS
-
- END
-